package tvs;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.lang.Thread;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpExchange;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;

import db.TvsDB;

//import chat.ChatService;
//import chat.HTTP;
//import chat.Player;
//import chat.PlayerList;


public class LobbyService {

	public static PlayerList playerList;
	public static GameList gameList;
	
	
	public static void main(String[] args) throws IOException, ServletException {
		playerList = new PlayerList();
		gameList = new GameList();
		Handler handler = new AbstractHandler()
	    {	
	    	//private ChatService chatService;
			List<String> chatList = new ArrayList<String>();
			//@Override
			public void handle(String target, Request request, HttpServletRequest MainRequestObject,
					HttpServletResponse response) throws IOException, ServletException
			{
				
				try
				{
				
					
					
					BufferedReader in = new BufferedReader(new InputStreamReader(MainRequestObject.getInputStream()));
					String line = null;
					StringBuilder PostedData = new StringBuilder();
					
					while ((line = in.readLine()) != null)
					{    							
						PostedData.append(line);
					}				
					
					System.out.println("received from client === " + request.getUri().toString() + " ::and:: " +  PostedData.toString());
					
					if(request.getUri().toString().equals("/get-salt"))
					{
						//How To Send Responce Back
						response.setContentType("text/html");
			            
			            String salt = Login.getSalt(PostedData.toString());
			            System.out.println(salt);
			            response.getWriter().println(salt);
			            response.setStatus(HttpServletResponse.SC_OK);
					}
					else if(request.getUri().toString().equals("/check-password"))
					{
						//How To Send Responce Back
						response.setContentType("text/html");
			            String responsestring = this.decipherMessage(PostedData.toString());
			            response.getWriter().println(responsestring);
			            response.setStatus(HttpServletResponse.SC_OK);
					}
					else if(request.getUri().toString().equals("/register-user"))
					{
						response.setContentType("text/html");
						String[] values = PostedData.toString().split("&");
						String username = values[0].split("=")[1];
						String password = values[1].split("=")[1];
						String playername = "";
						String email = "";
						if(values.length > 2)
						{
							playername = values[2].split("=")[1];
							email = values[3].split("=")[1];
							if(playername.equals("null")) playername = "";
							if(email.equals("null")) email = "";
						}
						String updateRes = "failure";
						if(!username.isEmpty() && !password.isEmpty())
						{
							updateRes = Login.registerUser(username, password, playername, email);
						}
			            response.getWriter().println(updateRes);
			            response.setStatus(HttpServletResponse.SC_OK);
					}
					else if(request.getUri().toString().equals("/register-user-salt"))
					{
						response.setContentType("text/html");
						String[] values = PostedData.toString().split("&");
						String username = values[0].split("=")[1];
						String salt = values[1].split("=")[1];
						String updateRes = "failure";
						if(!username.isEmpty() && !salt.isEmpty())
						{
							updateRes = Login.insertSalt(username, salt);
						}
			            response.getWriter().println(updateRes);
			            response.setStatus(HttpServletResponse.SC_OK);
					}
					else if(request.getUri().toString().equals("/ingame"))
					{
						response.setContentType("text/html");
						String responsestring = this.decipherMessage(PostedData.toString());
			            response.getWriter().println(responsestring);
			            response.setStatus(HttpServletResponse.SC_OK);
					}
					else if(request.getUri().toString().equals("/getchat"))
					{
						response.setContentType("text/html");
						String responsestring = this.getChatList();
			            response.getWriter().println(responsestring);
			            response.setStatus(HttpServletResponse.SC_OK);
					}
					else
					{
						response.setContentType("text/html");
						String responsestring = this.decipherMessage(PostedData.toString());
			            response.getWriter().println(responsestring);
			            response.setStatus(HttpServletResponse.SC_OK);
			            System.out.println("GET response string:" + responsestring);
					}
		            ((Request)MainRequestObject).setHandled(true);
		            System.out.println("----------------------------------------------");
					
				}
	        	catch (Exception ex)
	        	{
	        		System.out.println("Error: " + ex.getMessage());
				}
			}	
			
			private void runn()
			{
				
			}
			
			class MyThread implements Runnable {
					Player player;
					String parameter;
				   public MyThread(Player player, String parameter) {
				       // store parameter for later user
					   this.player = player;
					   this.parameter = parameter;
				   }

				   public void run() {
					   parameter = parameter.replace(" ", "_~~~_~_~~~_");
						HttpClient httpclient = new HttpClient();
						//httpclient.setFollowRedirects(false);
						try
						{
							httpclient.start();
							System.out.println("sending to client: " +player.getName() + " === " + "http://"+player.getIP()+"/query?"+parameter);
							System.out.println("----------------------------------------------");
							httpclient.GET("http://"+player.getIP()+"/query?"+parameter);
							httpclient.stop();

						}
						catch(Exception ex)
						{
							
						}
				   }
				}
			
			private void sendToClient(Player player, String parameter)
			{
				Runnable r = new MyThread(player, parameter);
				new Thread(r).start();
				//httpclient.
				
				/*
				
				HttpExchange exchange = new HttpExchange(null, null, null, null);
				 
				// Optionally set the HTTP method
				exchange.setMethod("POST");
				 
				exchange.setAddress(new Address("ping.host.com", 80));
				exchange.setURI("/ping");
				// Or, equivalently, this:
				exchange.setURL("http://ping.host.com/ping");
				 
				client.send(exchange);
				 
				System.out.println("Exchange sent");
				*/
			}
			
			private void sendToClient(String playerName, String parameter)
			{					
				Player player = null;
				for(Player p : playerList.getList())
				{
					if(p.getName().equals(playerName))
						player = p;
				}
				Runnable r = new MyThread(player, parameter);
				new Thread(r).start();
			}
			
			public String decipherMessage(String s) throws IOException
			{
				System.out.println("playercount: "+ playerList.getList().size());
				String[] strings = s.replace("_~~~_~_~~~_", " ").split("&");
				int isType = 0;
				String aux1 = "";
				String aux2 = "";
				String aux3 = "";
				String aux4 = "";
				String aux5 = "";
				String aux6 = "";
				String success = "";
				for(String str : strings)
				{
					String[] line = str.split("=");
					
					if(line[0].equals("type"))
					{
						if(line[1].equals("chat"))
						{
							isType=1;
						}
						if(line[1].equals("game"))
						{
							isType=2;
						}
						if(line[1].equals("player"))
						{
							isType=4;
						}
						if(line[1].equals("ingame"))
						{
							isType=3;
						}
					}
					else
					{
						if(isType == 1)
						{
							if(line[0].equals("username"))
								aux1 = line[1];
							if(line[0].equals("message"))
							{
								aux2 = line[1];
								/*System.out.println(aux2);
								if(aux2.contains("[personal]"))
								{
									String[] messageandpersonal = aux2.split("[personal]");
									aux3 = messageandpersonal[0 ];
									for(String stringggg : messageandpersonal)
									{
										System.out.println(stringggg);
									}
									aux2 = messageandpersonal[messageandpersonal.length-1].replace("]", "");
									System.out.println(aux3 + "::"+ aux2);
								}*/
								 
							}
							if(line[0].equals("personal"))
							{
								aux3 = line[1];
							}
							if(line[0].equals("subtype"))
							{
								aux4 = line[1];
							}
							if(line[0].equals("gameid"))
							{
								aux5 = line[1];
							}
						}
						if(isType == 2)
						{
							if(line[0].equals("subtype"))
							{
								aux1 = line[1];
							}
							if(line[0].equals("gamename"))
							{
								aux2 = line[1];
							}
							if(line[0].equals("ipaddress"))
							{
								aux3 = line[1];
							}
							if(line[0].equals("username"))
							{
								aux4 = line[1];
							}
							if(line[0].equals("settings"))
							{
								aux5 = line[1];
							}
							if(line[0].equals("gameid") || line[0].equals("id"))
							{
								aux6 = line[1];
							}
								
						}
						if(isType == 3)
						{
							
							
							if(line[0].equals("subtype"))
							{
								aux1 = line[1];
							}
							if(line[0].equals("gameid") || line[0].equals("id"))
							{
								aux2 = line[1];
							}
							if(line[0].equals("settings"))
							{
								aux3 = line[1];
							}
							if(line[0].equals("player"))
							{
								aux3 = line[1];
							}
							
							/*
							if(!aux1.equals("startgame"))
							{
								if(line[0].equals("changeoptions"))
								{
									aux3 = line[1];
								}
								if(aux1.split("-")[1].equals("player"))
								{
									if(line[0].equals("player"))
										aux3 = line[1];
								}
							}*/
						}
						if(isType == 4)
						{

							if(line[0].equals("subtype")){
								aux1 = line[1];
							}
							if(line[0].equals("username"))
							{
								aux2 = line[1];
							}
							if(line[0].equals("password"))
							{
								aux3 = line[1];
							}
							if(line[0].equals("ipaddress"))
							{
								aux4 = line[1];
							}
						}
					}
				};
				if(isType == 1)
				{
					String username = aux1;
					String message = aux2;
					String personal = aux3;
					String subtype = aux4;
					String gameid = aux5;
				    message = message.replace(" ", "_~~~_~_~~~_");
					List<Player> pList= playerList.getList();
					
					if(subtype.equals("ingame"))
					{
						Game g=gameList.getGame(gameid);
						String gList = g.getStringOfPlayers();
						System.out.println("check 1");
						//PlayerList pL = gList.getPlayerList();
						//System.out.println("check 2");
						System.out.println("check 2");
						System.out.println("check 3");
						for(String gp : gList.split("-"))
						{
							System.out.println("check 4");
							for(Player p : playerList.getList())
							{
								System.out.println("check 5");
								//if(gp.getName().equals(p.getName()) && !gp.getName().equals(playername) )
								if(gp.equals(p.getName()))
								{
									System.out.println("check 6");
									this.sendToClient(p, "lobby=gamelobby&type=chat&message="+message);
								}
							}
						}
						/*
						for(Player p : pList)
						{
							System.out.println("check 2");
							for(String g : pL2)//Player g : pL2)
							{
								System.out.println("check 3");
								//if(g.getName().equals(p.getName()))
								if(g.equals(p.getName()))
									this.sendToClient(p, "lobby=gamelobby&type=chat&message="+message);
								//if(p.getName() == username)
								//} 
								//HTTP.sendTextToPlayer(p, chatmessage);
							}
						}*/
						return "success";
					}
					else
					{
						if(personal.equals(""))
						{
							this.addToChatList(username + ": " + message);
						}
						else
						{
							this.addToChatList(username + "(personal:"+personal+"):" +  message);
						}
						if(personal.equals(""))
						{
							for(Player p : pList)
							{
								this.sendToClient(p, "lobby=mainlobby&type=chat&username="+username+"&message="+message);
								//if(p.getName() == username)
								//} 
								//HTTP.sendTextToPlayer(p, chatmessage);
							}
							return "success";
						}
						else     
						{
							for(Player p : pList)
							{
								if(p.getName().equals(personal))
								{                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
									this.sendToClient(p, "lobby=mainlobby&type=chat&username="+username+"&message="+message+"&personal="+personal);
								}
								//HTTP.sendTextToPlayer(p, chatmessage);
							}
							return "success";
						}
					}
				}
				
				if(isType == 2)
				{
					//game decipher
					String subtype = aux1;
					String gamename = aux2;
					String ip = aux3;
					String username = aux4;
					String settings = aux5;
					String id = aux6;
					if(subtype.equals("add"))
					{
						System.out.println("GameList size:"+gameList.getList().size());
						boolean gameAdded = gameList.addGame(new Game(gamename, ip, username, settings,id));//.newGame(gamename, ip, username, settings,id);
						gameList.addPlayerToGame(id, username);
						System.out.println("GameList size:"+gameList.getList().size());
						if(gameAdded)//gamename, username));
						{
							for(Player p : playerList.getList())
							{
								this.sendToClient(p, "lobby=mainlobby&type=game&subtype=add&gamename="+ gamename +"&ipaddress="+ip + "&gameid="+id+ "&settings="+settings + "&username="+username);
								
							}
						}
						return "success";
					}
					if(subtype.equals("remove"))
					{
						Game g = gameList.getGame(id);
						//System.out.println("test1");
						//for(Player gp : g.getPlayerList().getList())
						//for(Player gp : g.getPlayerList().getList())
						for(String gp : g.getPlayerList())
						{
							for(Player p : playerList.getList())
							{
								//if(gp.getName().equals(p.getName()))
								if(gp.equals(p.getName()) && !gp.equals(g.getUsername()))
								{
									this.sendToClient(p, "lobby=gamelobby&type=close");
								}
							}
						}
						gameList.removeGame(id);
						/*for(Game g : gameList.getList())
						{
							if(g.getId().equals(id))
							{
								gameList.removeGame(g);
							}
						}*/

						for(Player p : playerList.getList())
						{
							this.sendToClient(p, "lobby=mainlobby&type=game&subtype=remove&gameid=" + id);
						}
						//Game game = gameList.getGame(id);
						System.out.println("test1");
						//for(Player gp : g.getPlayerList().getList()
					}
					if(subtype.equals("all"))
					{
						Player p = playerList.getPlayer(username);
						for(Game g : gameList.getList())
						{
							this.sendToClient(p, "lobby=mainlobby&type=game&subtype=add&gamename="+ g.getName() +"&ipaddress="+ g.getIP() + "&gameid="+ g.getId() + "&settings="+ g.getSettings()+ "&username="+ g.getUsername());
							//this.sendToClient(username, "type=game&subtype=all&name="+name+"&ipaddress="+ip);
						}
						//allNames = allNames.substring(0, allNames.length()-1);
						
					}
					if(subtype.equals("banuser"))
					{
						gameList.addToGameBanList(id, username);
						this.sendToClient(playerList.getPlayer(username), "lobby=gamelobby&type=close");
						
					}
				}
				if(isType == 3)
				{
					String subtype = aux1;
					String gameid = aux2;
					String settings = aux3;
					String playername = aux3;
					System.out.println("------"+subtype + " " + gameid + " " + settings);
					if(subtype.equals("add-player"))
					{
						Game g = gameList.addPlayerToGame(gameid, playername);
						boolean confirmed = false;
						for(String p : g.getPlayerList())
						//for(Player p : g.getPlayerList().getList())
						{
							//if(p.getName().equals(playername))
							if(p.equals(playername))
							{
								confirmed = true;
								break;
							}
						}
						if(confirmed)
						{
							//for(Player gp : g.getPlayerList().getList())
							for(String gp : g.getPlayerList())
							{
								for(Player p : playerList.getList())
								{
									//if(gp.getName().equals(p.getName()) && !gp.getName().equals(playername) )
									if(gp.equals(p.getName()) && !gp.equals(playername) )
									{
										this.sendToClient(p, "lobby=gamelobby&type=add&data="+playername);
									}
								}
							}
							Game gdata = gameList.getGame(gameid);
							String[] setting = gdata.getSettings().split("-");
							return "gamename="+gdata.getName() + "&players=" +gdata.getPlayers() + "&maxplayers=" + setting[0] + "&lives="+setting[1] + "&time="+setting[2] + "&id="+gameid;
						}
						else
						{
							return "failure";
						}
					}
					if(subtype.equals("remove-player"))
					{
						Game g = gameList.removePlayerFromGame(gameid, playername);
						//for(Player gp : g.getPlayerList().getList())
						for(String gp : g.getPlayerList())
						{
							for(Player p : playerList.getList())
							{
								//if(gp.getName().equals(p.getName()))
								if(gp.equals(p.getName()))
								{
									this.sendToClient(p, "lobby=gamelobby&type=remove&data="+playername);
								}
							}
						}
						return "success";
					}
					if(subtype.equals("changeoptions"))
					{
						Game g = gameList.setSettingsToGame(gameid, settings);
						//for(Player gp : g.getPlayerList().getList())
						for(String gp : g.getPlayerList())
						{
							for(Player p : playerList.getList())
							{
								//if(gp.getName().equals(p.getName()))
								if(gp.equals(p.getName()) && !gp.equals(g.getUsername()))
								{
									this.sendToClient(p, "lobby=gamelobby&type=settings&data="+settings);
								}
							}
						}
						return "success";
					}
					if(subtype.equals("startgame"))
					{
						Game g = gameList.getGame(gameid);
						//for(Player gp : g.getPlayerList().getList())
						for(String gp : g.getPlayerList())
						{
							for(Player p : playerList.getList())
							{
								//if(gp.getName().equals(p.getName()))
								if(gp.equals(p.getName()))
								{
									this.sendToClient(p, "lobby=gamelobby&type=startgame");
								}
							}
						}
						return "success";
					}
				}
				if(isType == 4)
				{
					//player decipher
					String username = aux2;
					String subtype = aux1;
					String ip = aux4;
					String password = aux3;
					if(subtype.equals("add"))
					{
			            success = Login.loginPlayer(ip, username, password);
						if(success.equals("success"))
						{
				            for(Player p : playerList.getList())
							{
				            	if(!p.getName().equals(username))
				            		this.sendToClient(p, "lobby=mainlobby&type=player&subtype=add&name="+username);
								
							}
							System.out.println("Player Joined: "+ username);
						}
						else
						{
							System.out.println("Error: cannot login player: "+username);
						}
					}
					else if(subtype.equals("remove"))
					{
						playerList.removePlayer(username);
						for(Player p : playerList.getList())
						{
							this.sendToClient(p, "lobby=mainlobby&type=player&subtype=remove&name="+username);
						}
						System.out.println("Player Removed: "+ username);
					}
					else if(subtype.equals("all"))
					{
						String allNames = "";
						for(Player p : playerList.getList())
						{
							allNames = allNames + p.getName() + "-";
						}
						allNames = allNames.substring(0, allNames.length()-1);
						return "lobby=mainlobby&type=player&subtype=all&name="+allNames;
					}
					else if(subtype.equals("getinfo"))
					{
						Player player = playerList.getPlayer(username);
						String playerdatastring = player.getPlayerName() != "" ? "-"+player.getPlayerName() : "-null";
						playerdatastring += "-" + player.getEmail() != "" ? "-"+player.getEmail() : "-null";
						String returnString = player.getName() + playerdatastring + "-" + player.getWins() + "-" + player.getLosses();
						return returnString;
					}
				}
				return success;
			}
			
			public void addToChatList(String chatText)
			{
				if(chatList.size() > 30)
				{
					chatList.remove(0);
				}
				chatList.add(chatText);
			}
			
			public String getChatList()
			{
				String list = "";
				
				if(chatList.size() != 0)
				{
					for(String s : chatList)
					{
						list += s + "-";
					}
					list =  list.substring(0, list.length()-1);
				}
				return list;
			}
	    };
	    
		// TODO Auto-generated method stub
		Server server = new Server(8008); 
		server.setHandler(handler);
		try
		{
			server.start();
		}
		catch(Exception ex){
			System.out.println("Error: " + ex.getMessage());
		}
	}
}
